package org.cloud.storage;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.List;
import java.util.UUID;

import org.cloud.doc.Asset;
import org.cloud.doc.StorageMgr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.ClasspathPropertiesFileCredentialsProvider;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ListObjectsRequest;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectSummary;

public class S3StorageMgr implements StorageMgr {

    static Logger log = LoggerFactory.getLogger(S3StorageMgr.class);

    @Override
    public List<String> getDocumentList(String path) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Asset getDocumentByName(String path, String name) throws Exception {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public String saveOrUpdate(String path, String subFolder, InputStream fileStream) throws Exception {
        AmazonS3 s3 = new AmazonS3Client(new ClasspathPropertiesFileCredentialsProvider());
        Region usWest2 = Region.getRegion(Regions.US_WEST_2);
        s3.setRegion(usWest2);

        String bucketName = "my-first-s3-bucket-" + UUID.randomUUID();
        String key = "MyObjectKey";

        try {
            s3.createBucket(bucketName);
            /*
             * List the buckets in your account
             */
            for (Bucket bucket : s3.listBuckets()) {
                log.info(" - " + bucket.getName());
            }

            s3.putObject(new PutObjectRequest(bucketName, key, createSampleFile()));

            S3Object object = s3.getObject(new GetObjectRequest(bucketName, key));
            displayTextInputStream(object.getObjectContent());

            ObjectListing objectListing = s3.listObjects(new ListObjectsRequest().withBucketName(bucketName)
                    .withPrefix("My"));
            for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries()) {
                log.info(" - " + objectSummary.getKey() + "  " + "(size = " + objectSummary.getSize() + ")");
            }

            s3.deleteObject(bucketName, key);
            s3.deleteBucket(bucketName);
        } catch (AmazonServiceException ase) {
            log.info("Caught an AmazonServiceException, which means your request made it "
                    + "to Amazon S3, but was rejected with an error response for some reason.");
            log.info("Error Message:    " + ase.getMessage());
            log.info("HTTP Status Code: " + ase.getStatusCode());
            log.info("AWS Error Code:   " + ase.getErrorCode());
            log.info("Error Type:       " + ase.getErrorType());
            log.info("Request ID:       " + ase.getRequestId());
        } catch (AmazonClientException ace) {
            log.info("Caught an AmazonClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with S3, "
                    + "such as not being able to access the network.");
            log.info("Error Message: " + ace.getMessage());
        }
        return key;
    }

    /**
     * Creates a temporary file with text data to demonstrate uploading a file to Amazon S3
     * 
     * @return A newly created temporary file with text data.
     * 
     * @throws IOException
     */
    private static File createSampleFile() throws IOException {
        File file = File.createTempFile("aws-java-sdk-", ".txt");
        file.deleteOnExit();

        Writer writer = new OutputStreamWriter(new FileOutputStream(file));
        writer.write("abcdefghijklmnopqrstuvwxyz\n");
        writer.write("01234567890112345678901234\n");
        writer.write("!@#$%^&*()-=[]{};':',.<>/?\n");
        writer.write("01234567890112345678901234\n");
        writer.write("abcdefghijklmnopqrstuvwxyz\n");
        writer.close();

        return file;
    }

    /**
     * Displays the contents of the specified input stream as text.
     * 
     * @param input
     *            The input stream to display as text.
     * 
     * @throws IOException
     */
    private static void displayTextInputStream(InputStream input) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(input));
        while (true) {
            String line = reader.readLine();
            if (line == null)
                break;
        }
    }

    @Override
    public void close(Asset document) {
        // TODO Auto-generated method stub

    }

}
